---
title: AppManagerBase
summary: API reference for AppManagerBase.
status: draft
owner: SAIF Documentation
last_reviewed: 2026-08-21
library: SAIF.Application
reference_type: embedded
---

# AppManagerBase

`AppManagerBase` is the abstract lifecycle base every application manager in the solution (e.g. `ClaimAppManager`, and transitively `LegalManagerBase` and the `LegalNet` managers) inherits from `clsBusinessBase`. It owns identity binding, a lazily built data layer keyed to the authenticated user, the deny-by-default access classification, a de-duplicated message buffer, and the `MustOverride` extension points (`OnInitialize`, `OnCreateDataLayer`, `OnCheckSecurity`, `OnValidContext`, `OnRetrieve`, `OnWrite`, `OnTransactionStart`, `OnTransactionStop`) that derived managers must implement to complete the construct → initialize → validate-context → check-security → retrieve/write lifecycle.

## Purpose
- Guarantees every manager instance is bound to a `clsSecurityPrincipal` at construction time, since the only constructor requires one ([BR-APP-001](../../business-rules.md#br-app-001-manager-construction-requires-a-security-principal)).
- Enforces deny-by-default access classification through a private, `Mark*`-only-writable `AppSecurityRole` field ([BR-APP-002](../../business-rules.md#br-app-002-access-is-denied-by-default), [BR-APP-003](../../business-rules.md#br-app-003-access-classification-is-mutually-exclusive-and-read-only-externally)).
- Lazily provisions a per-manager `ApplicationDataAccess` data layer using the authenticated user's name as the DB client id ([BR-APP-007](../../business-rules.md#br-app-007-database-client-identity-is-the-requesting-user-unless-overridden)).
- Accumulates de-duplicated user-facing messages with a swappable line separator for web vs. console rendering ([BR-APP-005](../../business-rules.md#br-app-005-duplicate-message-text-is-never-shown-twice), [BR-APP-010](../../business-rules.md#br-app-010-messages-render-with-a-channel-appropriate-defaulted-separator)).
- Declares the `MustOverride` contract for context validation, security evaluation, retrieve/write, and transaction bracketing, leaving all domain-specific implementation to derived managers ([BR-APP-006](../../business-rules.md#br-app-006-a-write-must-be-bracketed-by-an-explicit-transaction)).

## Context
- Namespace: `SAIF.Application`
- Assembly/package: `SAIF.Application` (embedded, ProjectReference)
- Base type: `clsBusinessBase` (`SAIF.BOF.Framework.Core`)

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| `DefaultNewLineCharacter` | `Public Const String = "<BR>"` | Web-oriented default line separator applied when accumulating messages. |
| `MSG_SAVE` | `Public Const String = "Changes saved."` | Standard success message text shared by all managers. |
| `MSG_NO_SAVE` | `Public Const String = "No Changes to Save."` | Standard no-op message text shared by all managers. |
| `MSG_SAVE_FAILED` | `Public Const String = "Save failed."` | Standard failure message text shared by all managers. |
| `IsAccessible` | `Public ReadOnly Property As Boolean` | Reports whether the manager currently has any granted access (`Not (SecurityRole = NoAccess)`). |
| `IsRestricted` | `Public ReadOnly Property As Boolean` | Reports whether the manager is still at the deny-by-default classification (`SecurityRole = NoAccess`). |
| `IsUpdateable` | `Public ReadOnly Property As Boolean` | Reports whether the manager has been granted write access. |
| `IsViewOnly` | `Public ReadOnly Property As Boolean` | Reports whether the manager has been granted read-only access. |
| `Message` | `Public Property String` (getter public, `Protected Friend Set`) | Accumulated, de-duplicated user-facing message text; only the manager hierarchy may append to it. |
| `NewLineCharacter` | `Public Property String` | Separator injected between appended message lines, letting a console/Windows caller switch from `<BR>` to `vbCrLf`. |
| `SecurityRole` | `Public ReadOnly Property As AppSecurityRole` | Current access classification; defaults to `NoAccess` and can only be changed via the `Mark*` methods. |
| `ValidContext` | `Public ReadOnly Property As Boolean` | Delegates to the derived manager's `OnValidContext()` implementation. |
| `Retrieve` | `Public MustOverride Function As Boolean` | Public read entry point; implementation is supplied entirely by the derived manager. |
| `Write` | `Public MustOverride Function As Boolean` | Public write entry point; implementation is supplied entirely by the derived manager. |

### Nested type
| Member | Signature | Purpose |
| --- | --- | --- |
| `AppSecurityRole` | `Public Enum` (`ViewOnly`, `Update`, `NoAccess`) | The tri-state access classification bound by `SecurityRole`; documented separately at [AppManagerBase.AppSecurityRole](AppManagerBase.AppSecurityRole.md). |

### Protected members (available to derived managers)
| Member | Signature | Purpose |
| --- | --- | --- |
| `SecurityPrincipal` | `Protected ReadOnly Property As clsSecurityPrincipal` | Caller-supplied identity used for authorization decisions and as the data-layer client id; not exposed publicly, so only derived managers (e.g. `LegalManagerBase`) can reach it directly. |
| `DataLayer` | `Protected ReadOnly Property As ApplicationDataAccess` | Lazily creates `New ApplicationDataAccess(SecurityPrincipal.UserName.ToString)` on first access ([BR-APP-007](../../business-rules.md#br-app-007-database-client-identity-is-the-requesting-user-unless-overridden)). |
| `ContextSet` | `Protected ReadOnly Property As Boolean` | Whether business context (claim, case, etc.) has been supplied and validated. |
| `AppendMessageLines` | `Protected Sub (IEnumerable(Of String))` / `(String())` / `(String)` | Appends message lines, skipping empty text and duplicates ([BR-APP-005](../../business-rules.md#br-app-005-duplicate-message-text-is-never-shown-twice)). |
| `MarkContextNotSet` / `MarkContextSet` | `Protected Sub` | Toggle the context-validated flag read by `ContextSet`. |
| `MarkUpdate` / `MarkViewOnly` / `MarkNoAccess` | `Protected Sub` | The only writers of the access classification; called by a derived manager after evaluating security ([BR-APP-003](../../business-rules.md#br-app-003-access-classification-is-mutually-exclusive-and-read-only-externally)). |
| `Initialize` | `Protected Sub` | Template method: calls `OnInitialize()` then `OnCreateDataLayer()`, in that fixed order. |
| `New` | `Protected Sub New(inSecurityPrincipal As clsSecurityPrincipal)` | Only constructor; a manager cannot exist without an identity ([BR-APP-001](../../business-rules.md#br-app-001-manager-construction-requires-a-security-principal)). |
| `InjectDPI` | `Protected Sub (inKey As String, inDPI As IDataPortalInfo)` | Registers an externally created data-portal handle under `inKey` in the data layer's DPI registry. |
| `OnInitialize`, `OnCreateDataLayer`, `OnContextChanged`, `OnCheckSecurity`, `OnTransactionStart`, `OnTransactionStop(inCommit As Boolean)` | `Protected MustOverride Sub` | Extension points every concrete manager must implement; `OnCheckSecurity` and `OnContextChanged` are declared but never invoked from within this library. |
| `OnRetrieve`, `OnWrite`, `OnValidContext` | `Protected MustOverride Function As Boolean` | Derived read/write/context-validation implementations backing `Retrieve`, `Write`, and `ValidContext`. |

## Behavioral notes
- No parameterless constructor exists; a manager cannot be created without a `clsSecurityPrincipal` ([BR-APP-001](../../business-rules.md#br-app-001-manager-construction-requires-a-security-principal)).
- Field initializers set `m_AppSecurityRole = NoAccess`, `m_ContextSet = False`, `m_Message = String.Empty`, `m_NewLineCharacter = "<BR>"` at construction, establishing deny-by-default and empty-message state before `Initialize()` runs.
- `OnCheckSecurity()` and `OnContextChanged()` are declared but never called from within this library — a derived manager that never calls `OnCheckSecurity` stays at `NoAccess` (fail-closed) but also never grants access.*
- `System.Web` is referenced by the project and `<BR>` is the default message separator, so the message helpers are HTML-aware by convention even though this type has no compile-time UI dependency.*

## Constraints and usage notes
- `SecurityRole` and the derived `Is*` properties are read-only; the only way to change classification is through `MarkUpdate` / `MarkViewOnly` / `MarkNoAccess`, so no external caller can elevate its own rights ([BR-APP-003](../../business-rules.md#br-app-003-access-classification-is-mutually-exclusive-and-read-only-externally)).
- `Retrieve()` and `Write()` are `MustOverride`; this type supplies no default read/write behavior — the reference implementation lives in `SAIF.Application.Claim/ClaimAppManager.vb`.

> **Note:** Statements marked with `*` were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with `**` could not be confirmed; treat as unknown until verified.

## Sources
- `SAIF.Application/AppManagerBase.vb`
- `SAIF.Application.Claim/ClaimAppManager.vb`
